﻿namespace MySnake {
    //蛇
    export class Snake {
        private Audio: HTMLAudioElement; //多媒体
        private Container: HTMLTableElement; //容器类
        private Bodies: Array<SnakeBody> = new Array(); //蛇身
        private Direction: MoveDirection; //方向
        private Speed: number; //速度
        private IsPaused: boolean = true; //是否已经暂停
        private RowCount: number; //初始化行数
        private ColumnCount: number; //初始化列数
        private _Timer: number =1000; //计数器

        //构造函数 初始化
        constructor(_speed: number = 300, _rowCount: number = 50, _columnCount: number = 50) {
            this.Speed = _speed;
            this.RowCount = _rowCount;
            this.ColumnCount = _columnCount;
            this.Audio = <HTMLAudioElement>document.getElementById("bgMusic");
            this.Container = <HTMLTableElement>document.getElementById("tabContaniner");
            this.Direction = Math.floor(Math.random() * 4); //0-4 随机整数
            Music.SoundControl(this.Audio,0.2); //初始化音量（0.0-1.0）

            var x: number, y: number; //坐标
            
            //画表格
            for (let i = 0; i < this.RowCount; i++) {
                let _Row = <HTMLTableRowElement>this.Container.insertRow(-1);
                for (let j = 0; j < this.ColumnCount; j++) {
                    _Row.insertCell(-1);
                }
            }

            //随机产生食物
            for (var i = 0; i < 50; i++) {
                this.GenerateFood();
            }

            //产生蛇头
            while (true) {
                debugger;
                x = Math.floor(Math.random() * this.ColumnCount);
                y = Math.floor(Math.random() * this.RowCount);
                if (!Draw.IsCellFilled(this.Container, x, y)) {
                    (<HTMLTableCellElement>(<HTMLTableRowElement>this.Container.rows[y]).cells[x]).style.backgroundColor = Draw.GetRandomColor(); 
                    let _body = new SnakeBody();
                    _body.X = x;
                    _body.Y = y;
                    for(let i = 0;i < 3; i++){
                        this.Bodies.push(_body);
                    }
                    break;
                }
            }

            //事件响应
            document.onkeydown = (e) => {
                //监听键盘事件产生食物
                //this._Timer = setInterval(() => this.GenerateFood(), 10000);
                switch (e.keyCode | e.which | e.charCode) {
                    //Enter 回车键
                    case 13:
                        if (this.IsPaused) {
                            this.Run();
                            Music.GoGimes(this.Audio, PalyState.Play);
                            this.GimesMsg("游戏进行中!");
                        } else {
                            this.Pause();  //如果没有暂停，则停止移动
                            Music.GoGimes(this.Audio, PalyState.Pause);
                            this.GimesMsg("游戏暂停!");
                        }
                        break;

                    //左箭头
                    case 37:
                        //阻止蛇倒退走
                        if (this.Direction == MoveDirection.Right) {
                            break;
                        }
                        this.Direction = MoveDirection.Left;
                        break;

                    //上箭头
                    case 38:
                        //阻止蛇倒退走
                        if (this.Direction == MoveDirection.Down) {
                            break;
                        }
                        this.Direction = MoveDirection.Up;
                        break;

                    //右箭头
                    case 39:
                        //阻止蛇倒退走
                        if (this.Direction == MoveDirection.Left) {
                            break;
                        }
                        this.Direction = MoveDirection.Right;
                        break;

                    //下箭头
                    case 40:
                        //阻止蛇倒退走
                        if (this.Direction == MoveDirection.Up) {
                            break;
                        }
                        this.Direction = MoveDirection.Down;
                        break;
                }
            }

        }

        //暂停
        Pause() {
            clearInterval(this._Timer);
            if(!this.IsPaused){
                this.IsPaused = true;
            }
            Draw.Paint(this.Bodies, this.Container);
        }

        //蛇身运行到下一节点
        MoveNextStep() {
            //debugger;

            //游戏结束: 【到达边界】或者【碰到蛇身】
            if (Draw.CheckNextStep(this.Bodies, this.Direction, this.ColumnCount, this.RowCount, this.Container) == -1) {
                Music.GoGimes(this.Audio, PalyState.Stop);
                //alert("游戏结束");
                this.GimesMsg("游戏结束!");
                this.Pause(); //游戏暂停
                return;
            }

            //遇到食物
            if (Draw.CheckNextStep(this.Bodies, this.Direction, this.ColumnCount, this.RowCount, this.Container) == 1) { 
                this.GimesMsg("吃到食物了!");
                //产生食物
                this.GenerateFood();
                let newBody = Draw.GetNextPosition(this.Bodies, this.Direction);
                this.Bodies.unshift(newBody); //长身体
                return;
            }

            let newBody = Draw.GetNextPosition(this.Bodies, this.Direction);
            this.Bodies.unshift(newBody);
            this.Bodies.pop(); //没吃到食物，就移除最后的点元素
        }

        //蛇身运动
        Run() {
            if(this.IsPaused){
                this.IsPaused = false;
            }
            var _Snake = this;
            this._Timer = setInterval(() => {
                Draw.Erase(_Snake.Bodies, _Snake.Container);
                _Snake.MoveNextStep();
                Draw.Paint(_Snake.Bodies, _Snake.Container);
            }, this.Speed);
        }

        //随机产生食物
        GenerateFood() {
            var x: number = Math.floor(Math.random() * this.ColumnCount);
            var y: number = Math.floor(Math.random() * this.RowCount);
            if (!Draw.IsCellFilled(this.Container, x, y)) {
                (<HTMLTableCellElement>(<HTMLTableRowElement>this.Container.rows[y]).cells[x]).style.backgroundColor = Draw.GetRandomColor();
            }
        }

        //游戏提示
        GimesMsg(msg: string) {
            console.log(msg);
        }  
    } 

    //运行调用
    window.onload = () => {
        //debugger;
        //let _Snake = new Snake();
        let _Snake = new Snake(500, 50, 50); 
    }
}